#include <rtthread.h>
#include <webclient.h>

#include <string.h>
#include "cJSON_util.h"

#include <arpa/inet.h> 
#include <netdev.h>
#include <ntp.h>

#define GET_HEADER_BUFSZ          2048
#define GET_RESP_BUFSZ            2048
#define GET_RESP_CONTENTSZ        4096
#define URL_LEN_MAX               2048

// 请更新为自己申请地心知API
#define GET_LOCAL_URI                "http://api.seniverse.com/v3/weather/daily.json?key=SbIF5GG3xcL_0d8Jt&location=beijing&language=zh-Hans&unit=c&start=-1&days=5"
//#define GET_LOCAL_URI                "http://api.seniverse.com/v3/weather/daily.json?key=S97hL3kj6EbnjEmyC&location=%s&language=zh-Hans&unit=c&start=0&days=5"

#define LOCAL_CITY                   "ip"        //实际自动识别请求 IP 地址 

typedef struct weather_info {
	char date[8];				
	char text_day[8];		
	char code_day[8];	
	char text_night[8];	
	char high[8];	
	char low[8];		
	char wind_direction[8];		
	char wind_speed[8];		
	char rainfall[8];	
	char humidity[8];	
} weather_info_t;
static weather_info_t ui_weather_info[3];
char *gfxvalue;

static struct rt_mailbox mb_weather;
static char mb_pool[16];

static void weather_data_parse(char* data)
{
   cJSON *root = RT_NULL, *arrayItem = RT_NULL,*object = RT_NULL, *object2 = RT_NULL,*list = RT_NULL, *item = RT_NULL, *weatheritem = RT_NULL;
        int index, list_size = 0;
   root = cJSON_Parse((const char *)data);
   if (!root)
   {
       rt_kprintf("No memory for cJSON root!\n");
       return;
   }
   arrayItem = cJSON_GetObjectItem(root, "results"); 
    if (arrayItem == RT_NULL)
    {
        rt_kprintf("cJSON get results failed.");
        goto __EXIT;
    }   

	 object = cJSON_GetArrayItem(arrayItem, 0); 
	 if (object == RT_NULL)
    {
        rt_kprintf("cJSON get object failed.");
        goto __EXIT;
    } 
	item = cJSON_GetObjectItem(object, "location");  /* 匹配子对象1 */
    if (item == RT_NULL)
    {
        rt_kprintf("cJSON get location failed.");
        goto __EXIT;
    } 
	if((list = cJSON_GetObjectItem(item,"name")) != NULL)   
	{
		rt_kprintf("city: %s\r\n",list->valuestring);
	}
	object2 = cJSON_GetObjectItem(object, "daily");  /* 匹配子对象2 */
	int size = cJSON_GetArraySize(object2);     //获取数组中对象个数
	rt_kprintf("\n");
	for(int i = 0 ;i<size;i++ )
	{
		item = cJSON_GetArrayItem(object2, i); 
		if (item == RT_NULL)
		{
			rt_kprintf("cJSON get daily failed.");
			goto __EXIT;
		} 
		if((list = cJSON_GetObjectItem(item,"date")) != NULL)   
		{
			rt_kprintf("date: %s\r\n",list->valuestring);
		}
		if((list = cJSON_GetObjectItem(item,"text_day")) != NULL)   
		{
			rt_kprintf("text_day: %s\r\n",list->valuestring);
		}
		if((list = cJSON_GetObjectItem(item,"text_night")) != NULL)   
		{
			rt_kprintf("text_night: %s\r\n",list->valuestring);
		}	
		if((list = cJSON_GetObjectItem(item,"high")) != NULL)   
		{
			rt_kprintf("high: %s\r\n",list->valuestring);
		}
		if((list = cJSON_GetObjectItem(item,"low")) != NULL)   
		{
			rt_kprintf("low: %s\r\n",list->valuestring);
		}	
		if((list = cJSON_GetObjectItem(item,"wind_direction")) != NULL)   
		{
			rt_kprintf("wind_direction: %s\r\n",list->valuestring);
		}
		if((list = cJSON_GetObjectItem(item,"wind_speed")) != NULL)   
		{
			rt_kprintf("wind_speed: %s\r\n",list->valuestring);
		}
		if((list = cJSON_GetObjectItem(item,"rainfall")) != NULL)   
		{
			rt_kprintf("rainfall: %s\r\n",list->valuestring);
		}
		if((list = cJSON_GetObjectItem(item,"humidity")) != NULL)   
		{
			rt_kprintf("humidity: %s\r\n",list->valuestring);
		}	
		rt_kprintf("\n");
	}

__EXIT:
   if (root != RT_NULL)
       cJSON_Delete(root);        
}

int get_weather(int argc, char **argv)
{
    struct webclient_session* session = RT_NULL;
    unsigned char *buffer = RT_NULL;
    char *URI = RT_NULL;
    int index, ret = 0;
    int bytes_read, resp_status;
    int content_length = -1;
    char *city_name = rt_calloc(1,255);
    
    if(argc == 1)
    {
        strcpy(city_name, LOCAL_CITY);
    }
    else if (argc == 2)
    {
        strcpy(city_name, argv[1]);
                urlencode(city_name);//对中文编码
    }
    else if(argc > 2)
    {
        rt_kprintf("wt [CityName]  - webclient GET request test.\n");
        return -1;
    }
        URI = rt_calloc(1, URL_LEN_MAX);        
        rt_snprintf(URI, URL_LEN_MAX, GET_LOCAL_URI, city_name);
    buffer = (unsigned char *) web_malloc(GET_RESP_CONTENTSZ);
    if (buffer == RT_NULL)
    {
        rt_kprintf("no memory for receive buffer.\n");
        ret = -RT_ENOMEM;
        goto __exit;
    }

    /* create webclient session and set header response size */
    session = webclient_session_create(GET_HEADER_BUFSZ);
    if (session == RT_NULL)
    {
        ret = -RT_ENOMEM;
        goto __exit;
    }

    /* send GET request by default header */
        rt_kprintf("send GET request to %s\n", URI);
    if ((resp_status = webclient_get(session, URI)) != 200)
    {
        rt_kprintf("webclient GET request failed, response(%d) error.\n", resp_status);
        ret = -RT_ERROR;
        goto __exit;
    }
    content_length = webclient_content_length_get(session);
    if (content_length < 0)
    {
        rt_kprintf("webclient GET request type is chunked.\n");
        do
        {
            bytes_read = webclient_read(session, buffer, GET_RESP_BUFSZ);
            if (bytes_read <= 0)
            {
                break;
            }

            for (index = 0; index < bytes_read; index++)
            {
                rt_kprintf("%c", buffer[index]);
            }
        } while (1);
        rt_kprintf("\n");
    }
    else
    {
        int content_pos = 0;
        do
        {
            bytes_read = webclient_read(session, buffer+content_pos, GET_RESP_BUFSZ);
            if (bytes_read <= 0)
            {
                                break;
            }
            content_pos += bytes_read;
        } while (content_pos < content_length);
        weather_data_parse((char*)buffer);
    }

__exit:
    if (session)
    {
        webclient_close(session);
    }

    if (buffer)
    {
        web_free(buffer);
    }

    if (URI)
    {
        web_free(URI);
    }

    return ret;
}


weather_info_t  *gfxget_weather_date(void)
{
	if (rt_mb_recv(&mb_weather, (rt_ubase_t *)&ui_weather_info, RT_WAITING_NO) == RT_EOK)
	{
		return ui_weather_info;
	}
	else
	{
		return RT_NULL;
	}
    
}

static void weather_update_thread_entry(void *parameter)
{
	// 获取网卡对象
	struct netdev* net = netdev_get_by_name("w0");
    
	//阻塞判断当前网络是否正常连接
	while( netdev_is_internet_up(net) != 1)
	{
	   rt_thread_mdelay(200);
	}
    
	if( 0 == get_weather(1,0) )
	{
		rt_mb_send(&mb_weather, (rt_uint32_t)ui_weather_info);
	}
    
	while(1)
	{
		rt_thread_mdelay(5000);
		rt_mb_send(&mb_weather, (rt_uint32_t)ui_weather_info);		
	}
}

int weather_update_init(void)
{
	rt_err_t result = RT_EOK;
	/* 初始化mailbox */
    result = rt_mb_init(&mb_weather,
                        "weather_mbt",              /* 名称是 weather_mbt */
                        &mb_pool[0],                /* 邮箱用到的内存池是 mb_pool */
                        sizeof(mb_pool) / 4,        /* 邮箱中的邮件数目，因为一封邮件占 4 字节 */
                        RT_IPC_FLAG_FIFO);          /* 采用 FIFO 方式进行线程等待 */
    if (result != RT_EOK)
    {
        rt_kprintf("init mailbox failed.\n");
        return -1;
    }

    rt_thread_t tid1 = RT_NULL;
    /* 创建线程*/
    tid1 = rt_thread_create("weather",
            weather_update_thread_entry, RT_NULL,
                            1024,12, 5);

    /* 如果获得线程控制块，启动这个线程 */
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);

    return 0;
}

//#ifdef FINSH_USING_MSH
#include <finsh.h>
//MSH_CMD_EXPORT_ALIAS(get_weather, wt, wt [CityName]  webclient GET request test);
MSH_CMD_EXPORT(get_weather, Lwebclient GET request test);
//#endif /* FINSH_USING_MSH */